package org.idea.spring.look.up.lazy;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

import java.util.Iterator;

/**
 * @Author linhao
 * @Date created in 3:58 下午 2021/4/11
 */
public class LazyLoadBean {

    static class Bus {
        int id;

        @Override
        public String toString() {
            return "Bus{" +
                    "id=" + id +
                    '}';
        }

        public Bus(int id) {
            this.id = id;
        }

        public static Bus buildBus(){
            return new Bus(1);
        }
    }

    @Bean
    @Primary
    public String helloWorld(){
        return "hello world";
    }

    @Bean
    public String message(){
        return "message";
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(LazyLoadBean.class);
//        annotationConfigApplicationContext.register(Bus.class);
        annotationConfigApplicationContext.refresh();
        //ObjectProvider 可以不需要通过initLazy这种配置方式处理懒加载问题，借助程序实现懒加载
        lookupByObjectProvider(annotationConfigApplicationContext);
        lookUpByPrimary(annotationConfigApplicationContext);
        lookUpIter(annotationConfigApplicationContext);
        lookUpStream(annotationConfigApplicationContext);
    }

    public static void lookupByObjectProvider(AnnotationConfigApplicationContext annotationConfigApplicationContext){
        ObjectProvider<Bus> objectProvider = annotationConfigApplicationContext.getBeanProvider(Bus.class);
        //类型安全的策略
        Bus bus = objectProvider.getIfAvailable(Bus::buildBus);
        System.out.println(bus.toString());
    }

    public static void lookUpByPrimary(AnnotationConfigApplicationContext annotationConfigApplicationContext){
        ObjectProvider<String> objectProvider = annotationConfigApplicationContext.getBeanProvider(String.class);
        System.out.println(objectProvider.getObject());
    }

    public static void lookUpIter(AnnotationConfigApplicationContext annotationConfigApplicationContext) {
        ObjectProvider<String> objectProvider = annotationConfigApplicationContext.getBeanProvider(String.class);
        Iterator<String> iterator = objectProvider.iterator();
        while(iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);
        }
    }

    public static void lookUpStream(AnnotationConfigApplicationContext annotationConfigApplicationContext) {
        ObjectProvider<String> objectProvider = annotationConfigApplicationContext.getBeanProvider(String.class);
        objectProvider.stream().forEach(System.out::println);
    }
}
